#!/usr/bin/perl

use strict;
use warnings;
use IO::Socket;
use File::Basename;
use Getopt::Long;
use Sys::Hostname;

our (
    $LOGFILE,
    $PROGNAME,
    %OPTS,
);

sub startup
{
    $PROGNAME = basename $0;
    $OPTS{p} = 514;
    $OPTS{i} = 0.005;
    $OPTS{n} = 1;
}

sub usage
{
    print << "END";
Usage: $PROGNAME -h | --help 
       $PROGNAME -r remote-addr [-p remote-port] [-l local-addr] [-i interavl] [-n count] logfile 

    -h, --help      Help
    -r remote-addr  IP address of syslog server.       
    -p remote-port  Port of syslog server, default 514.
    -l local-addr   IP address of the simulated device.
    -i interval     Sleep interval seconds after sent one log, default 0.005.
    -n count        How many times the logs in the file will be sent, default 1. 
                    Set to 0 to send logs infinite times.

Report bugs to Qianjun Xia <qxia at a10networks.com.cn>\n
END
}

sub get_args
{
    Getopt::Long::Configure("bundling");
    if (
        ! GetOptions(
            \%OPTS,
            "h|help",
            "r=s",
            "p=i",
            "l=s",
            "i=f",
            "n=i",
        )
    ) {
        usage();
        exit 1;
    }

    ($LOGFILE) = @ARGV;

    if ($OPTS{"h"}) {
        usage();
        exit 0;
    }

    if (!defined($LOGFILE) || !defined($OPTS{"r"})) {
        usage();
        exit 1;
    }
    
    if($OPTS{"i"} < 0) {
        print "Invalid interval.\n";
        exit 1;
    }
}

sub send_logs
{
    my ($data, $count);
    my $repeat = $OPTS{"n"};
    my $interval = $OPTS{"i"};
    my $sock;

    if (defined $OPTS{"l"}) {
        $sock = IO::Socket::INET->new(
                    PeerAddr => $OPTS{"r"},
                    PeerPort => $OPTS{"p"},
                    LocalAddr => $OPTS{"l"},
                    Proto    => 'udp')
            or die "Can't connect: $!\n";
    } else {
        $sock = IO::Socket::INET->new(
                    PeerAddr => $OPTS{"r"},
                    PeerPort => $OPTS{"p"},
                    Proto    => 'udp')
            or die "Can't connect: $!\n";
    }

    open LOG_FILE, "<$LOGFILE";

    $count = 0;
    for (my $i = 0; $repeat == 0 || $i<$repeat; $i++) {
        seek LOG_FILE, 0, 0;
        while (1) {
            $data = <LOG_FILE>;
            if (!defined($data)) {
               last;
            }
            $sock->send($data, 0);
            #print $data;
            $count++;

            if ($interval > 0) {
               select(undef, undef, undef, $interval);
            }
            if ($count % 300 == 0) {
               print "$count logs sent.\n";
            }
        }
    }
    close(LOG_FILE);
    $sock->close();
}

main:
{
    startup();
    get_args();
    send_logs();
    exit 0;
}
